package com.example.service.impl;

import ch.qos.logback.classic.Logger;
import com.example.entity.MessageNotice;
import com.example.entity.authority.Party;
import com.example.entity.supervision.PlanDetail;
import com.example.entity.supervision.PlanDict;
import com.example.entity.supervision.PublicRandom;
import com.example.entity.supervision.PublicRandomResult;
import com.example.ext.entity.ExtParty;
import com.example.mapp.*;
import com.example.service.PublicRandomService;
import com.example.util.ExportExcelUtil;
import com.example.util.ResultUtil;
import com.example.util.StringUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by simon on 2018/9/11.
 */
@Service
public class PublicRandomServiceImpl implements PublicRandomService {

    private final static Logger logger = (Logger) LoggerFactory.getLogger(PublicRandomServiceImpl.class);

    @Autowired
    PublicRandomMapp publicRandomMapp;
    @Autowired
    Environment environment;

    @Autowired
    ElevatorMapp elevatorMapp;

    @Autowired
    PartyMapp partyMapp;

    @Autowired
    PlanDictMapp planDictMapp;

    @Autowired
    PlanDetailMapp planDetailMapp;

    @Autowired
    MessageNoticeMapp messageNoticeMapp;




    @Override
    public Map<String, Object> query(PublicRandom publicRandom) {

        List<PublicRandom> list = null;
        Map<String, Object> map = new HashMap();
        try {
            Page<ExtParty> page = PageHelper.startPage(publicRandom.getCurrentPage(), publicRandom.getPageSize());
            list = publicRandomMapp.query(publicRandom);
            map.put("list", list);
            map.put("total", page.getTotal());

            return ResultUtil.returnSuccess("查询成功", map);
        } catch (Exception e) {
            logger.error("查询失败：" + e.getMessage(), e);
            return ResultUtil.returnError("查询失败", null);
        }
    }

    @Override
    @Transactional
    public Map<String, Object> add(PublicRandom publicRandom) {
        try {

            publicRandomMapp.insert(publicRandom);
            return ResultUtil.returnSuccess("新增成功", null);
        } catch (Exception e) {
            logger.error("新增失败：" + e.getMessage(), e);
            return ResultUtil.returnError("新增失败", null);
        }
    }

    @Override
    @Transactional
    public Map<String, Object> delete(PublicRandom publicRandom) {
        try {
            publicRandomMapp.delete(publicRandom);
            return ResultUtil.returnSuccess("删除成功", null);
        } catch (Exception e) {
            logger.error("删除失败：" + e.getMessage(), e);
            return ResultUtil.returnError("删除失败", null);
        }
    }

    @Override
    @Transactional
    public Map<String, Object> update(PublicRandom publicRandom) {
        try {
            int i = publicRandomMapp.update(publicRandom);
            return ResultUtil.returnSuccess("更新成功", null);
        } catch (Exception e) {
            logger.error("更新失败：" + e.getMessage(), e);
            return ResultUtil.returnError("更新失败", null);
        }
    }

    @Override
    @Transactional
    public Map<String, Object> addRes(Map map) {
        try {

            if(map !=null && map.size()>0){
                // 先去查询任务有没有做完
                PublicRandom random = new PublicRandom();
                random.setId(Long.valueOf(map.get("randomId").toString()));
                random = publicRandomMapp.findState(random);

                if(StringUtils.isNotBlank(random.getFinish())){
                    return ResultUtil.returnError("新增失败,该计划已经完成,请前去现场监督检查计划功能下,新增检查项", null);
                }

                PlanDict plan = new PlanDict();
                plan.setPdName(map.get("planName").toString());
                // 专项检查
                plan.setPdType("3");
                plan.setpPartyId(map.get("partyId").toString());
                plan.setpPartyName(map.get("partyName").toString());
                plan.setpUserId(map.get("userId").toString());
                plan.setpUserName(map.get("userName").toString());
                plan.setpStartDt(map.get("beginTime").toString());
                plan.setpEndDt(map.get("endTime").toString());
                plan.setExt1("双随机");
                planDictMapp.insert(plan);


                List<Map<String,Object>> resultmap = (List<Map<String, Object>>) map.get("resuList");

                for(Map<String,Object> result : resultmap){
                    PlanDetail planDetail = new PlanDetail();
                    planDetail.setBeCkedPartyId(result.get("id").toString());
                    planDetail.setBeCkedPartyName(result.get("name").toString());
                    planDetail.setBePartyType("使用单位");
                    planDetail.setRsponPartyId(map.get("partyId").toString());
                    planDetail.setRsponPartyName(map.get("partyName").toString());
                    planDetail.setRsponUserId(result.get("userId").toString());
                    planDetail.setRsponUserName(result.get("pname").toString());

                    planDetail.setPlanDictId(plan.getId().toString());

                    planDetail.setIsAdjustment("0");
                    planDetail.setCheckState("0");
                    planDetail.setExt1("双随机");
                    planDetailMapp.insert(planDetail);


                    List<String> splitId = Arrays.asList(planDetail.getRsponUserId().split(","));
                    List<String> splitName = Arrays.asList(planDetail.getRsponUserName().split(","));

                    for (int i = 0; i < splitId.size(); i++) {
                        // 发送通知
                        String noticeTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
                        MessageNotice messageNotice = new MessageNotice();
                        String content = splitName.get(i).trim()+"：您好，"+planDetail.getBeCkedPartyName()+" 需要进行现场监督检查，请及时处理。";
                        messageNotice.setTitle("新监督检查任务");
                        messageNotice.setContent(content);
                        messageNotice.setIsRead("0");
                        messageNotice.setNoticeTime(noticeTime);
                        messageNotice.setReceivePartyId(planDetail.getRsponPartyId());
                        messageNotice.setSendUserId(null);
                        messageNotice.setReceiveUserId(splitId.get(i).trim());
                        messageNoticeMapp.add(messageNotice);
                    }
                }
                // 导入成功后，修改双随机表里的标志
                Map updatemap = new HashMap();
                updatemap.put("id",map.get("randomId").toString());
                publicRandomMapp.updateState(updatemap);

            }
        } catch (Exception e) {
            logger.error("新增失败：" + e.getMessage(), e);
            return ResultUtil.returnError("新增失败", null);
        }
        return ResultUtil.returnSuccess("新增成功", null);
    }

    /**
     * 导出分配结果
     * @param publicRandomResultList
     * @return
     */
    @Override
    public Map<String, Object> exportRes(Map<String, List<PublicRandomResult>> publicRandomResultList) {
        Map<String, Object> result = new HashMap<>();
        List<PublicRandomResult> list = publicRandomResultList.get("resList");
        FileOutputStream fileOutStream = null;
        try {
            // 1.获取保存路径，不存在则创建
            String path = environment.getProperty("upload", String.class);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String dateString = sdf.format(new Date());
            if (path.endsWith(File.separator)) {
                path = path + dateString + File.separator;
            } else {
                path = path + File.separator + dateString + File.separator;
            }
            File file1 = new File(path);
            if (!file1.exists()) {
                boolean flag = file1.mkdirs();
            }
            // 重现生成文件名，防止中文乱码
            String fileName = UUID.randomUUID() + ".xlsx";
            path = path + fileName;
            result.put("fileUrl", dateString + File.separator + fileName);
            result.put("fileName", "双随机一公开结果.xlsx");

            // 2.创建workbook和sheet
            fileOutStream = new FileOutputStream(path);
            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet sheet = wb.createSheet("双随机一公开结果");
            sheet.setColumnWidth(0, 50 * 256);
            sheet.setColumnWidth(1, 20 * 256);
            sheet.setColumnWidth(2, 20 * 256);
            sheet.setColumnWidth(3, 20 * 256);
            sheet.setColumnWidth(4, 20 * 256);
            sheet.setColumnWidth(5, 20 * 256);
            sheet.setColumnWidth(6, 20 * 256);
            sheet.setColumnWidth(7, 20 * 256);
//            sheet.protectSheet("hyelevator");
            // 3.绘制表头
            XSSFCellStyle headStyle = wb.createCellStyle();
            headStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 水平居中
            headStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER); // 垂直居中
            headStyle.setBorderBottom(XSSFCellStyle.BORDER_MEDIUM); // 中等边线
            headStyle.setBorderTop(XSSFCellStyle.BORDER_MEDIUM); // 中等边线
            headStyle.setBorderLeft(XSSFCellStyle.BORDER_MEDIUM); // 中等边线
            headStyle.setBorderRight(XSSFCellStyle.BORDER_MEDIUM); // 中等边线

            XSSFFont headFont = wb.createFont();
            headFont.setFontName("宋体");
            headFont.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
            headFont.setFontHeightInPoints((short) 14);
            headStyle.setFont(headFont);

            // 3.3 获取第一行
            XSSFRow headRow = sheet.createRow(0);
            headRow.setHeightInPoints(30f); // 设置第一行高度
            // 3.4 绘制表头
            XSSFCell headerCell1 = headRow.createCell(0);
            headerCell1.setCellValue("单位名称");
            headerCell1.setCellStyle(headStyle);

            XSSFCell headerCell2 = headRow.createCell(1);
            headerCell2.setCellValue("单位编号");
            headerCell2.setCellStyle(headStyle);

            XSSFCell headerCell3 = headRow.createCell(2);
            headerCell3.setCellValue("单位类型");
            headerCell3.setCellStyle(headStyle);

            XSSFCell headerCell4 = headRow.createCell(3);
            headerCell4.setCellValue("牵头单位");
            headerCell4.setCellStyle(headStyle);

            XSSFCell headerCell5 = headRow.createCell(4);
            headerCell5.setCellValue("牵头单位编号");
            headerCell5.setCellStyle(headStyle);

            XSSFCell headerCell6 = headRow.createCell(5);
            headerCell6.setCellValue("牵头人");
            headerCell6.setCellStyle(headStyle);

            XSSFCell headerCell7 = headRow.createCell(6);
            headerCell7.setCellValue("牵头人编号");
            headerCell7.setCellStyle(headStyle);

            //4 组装数据
            for (int i = 0; i < list.size(); i++) {
                // 4.1 创建一行
                XSSFRow row = sheet.createRow(i + 1);
                // 4.2 绘制数据
                XSSFCell rowCell1 = row.createCell(0);
                rowCell1.setCellValue(list.get(i).getBeCkedPartyName());

                XSSFCell rowCell2 = row.createCell(1);
                rowCell2.setCellValue(list.get(i).getBeCkedPartyId());

                XSSFCell rowCell3 = row.createCell(2);
                rowCell3.setCellValue(list.get(i).getBePartyType());

                XSSFCell rowCell4 = row.createCell(3);
                rowCell4.setCellValue(list.get(i).getRsponPartyName());

                XSSFCell rowCell5 = row.createCell(4);
                rowCell5.setCellValue(list.get(i).getRsponPartyId());

                XSSFCell rowCell6 = row.createCell(5);
                rowCell6.setCellValue(list.get(i).getRsponUserName());

                XSSFCell rowCell7 = row.createCell(6);
                rowCell7.setCellValue(list.get(i).getRsponUserId());
            }

            wb.write(fileOutStream);
            return ResultUtil.returnSuccess("导出成功", result);
        } catch (Exception e) {
            logger.error("导出失败：" + e.getMessage(), e);
            return ResultUtil.returnError("导出失败", null);
        }finally {
            if(fileOutStream != null){
                try{
                    fileOutStream.flush();
                    fileOutStream.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    public Map<String, Object> exportResAft(Map prId) {
        try {
            List<PublicRandomResult> list = publicRandomMapp.queryRes(prId);
            Map resmap = new HashMap();
            resmap.put("resList", list);
            return this.exportRes(resmap);
        } catch (Exception e) {
            logger.error("新增失败：" + e.getMessage(), e);
            return ResultUtil.returnError("新增失败", null);
        }
    }

    /**
     * 导出 双随机主体单位
     */
    @Override
    public Map<String, Object> exportRandomPort(Map map) {
        String message = "导出成功";
        Map<String, Object> result = new HashMap<>();
        try {
            if (map.get("elevatorPlaceParam") != null) {
                String elevatorPlaceParam = map.get("elevatorPlaceParam").toString();
                if (StringUtil.isNotBlank(elevatorPlaceParam)) {
                    List<String> place = Arrays.asList(elevatorPlaceParam.split(","));
                    map.put("elevatorPlaceParam", place);
                }
            }
            List<Map<String, Object>> list = elevatorMapp.getElevatorList(map);
            //如果查询结果不为空，则创建表格，否则不创建
            if (list != null && list.size() > 0) {
                // 1.获取保存路径，不存在则创建
                String tableName = "筛选主体单位种子数据";//表名；
                // 创建 表头
                String[] tableN = {"注册代码", "安装地点", "使用单位", "维保单位", "场所", "梯型"};

                String[] tableE = {"elevatorNum", "buildAddr", "usedPartyName", "maintenancePartyName", "elevatorPlace", "typeName"};
                List<String> tablelist = Arrays.asList(tableN);
                List<String> tablelistEc = Arrays.asList(tableE);
                String path = environment.getProperty("upload", String.class);
                result = ExportExcelUtil.writeMapExcel(tableName, tablelist, tablelistEc, list, path);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            return ResultUtil.returnError(e.getMessage(), null);
        }
        return ResultUtil.returnSuccess(message, result);
    }

    /**
     * 双随机获取监管单位
     *
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> findUnit(Map map) {
        String message = "查询成功";
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            if (map != null && map.size() > 0) {
                String id = map.get("id").toString();
                String limit = decideInfo(id);

                if ("0".equals(limit) || "1".equals(limit)) {
                    // 0市 1是局
                    list = publicRandomMapp.findUnitCity(id);
                } else {
                    list = publicRandomMapp.findUnitArea(id);
                }
            }
        } catch (Exception e) {
            logger.error("查询失败：" + e.getMessage(), e);
            return ResultUtil.returnError("查询失败", null);
        }
        return ResultUtil.returnSuccess(message, list);
    }

    /**
     * 双随机获取监管单位下的用户信息
     *
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> queryUnit(Map map) {
        String message = "查询成功";
        List<Map<String, Object>> list =null;
        try {
            if (map.get("userType") != null) {
                String userType = map.get("userType").toString();
                if (StringUtil.isNotBlank(userType)) {
                    List<String> type = Arrays.asList(userType.split(","));
                    map.put("userType", type);
                }
            }
            list = publicRandomMapp.queryUserByUnit(map);

        } catch (Exception e) {
            logger.error("查询失败：" + e.getMessage(), e);
            return ResultUtil.returnError("查询失败", null);
        }
        return ResultUtil.returnSuccess(message, list);
    }

    /**
     * 双随机点击开始分配
     *
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> startDistribution(Map map) {
        String message = "查询成功";
        // 封装最后数据
        List<Map<String,Object>> unitlist = new ArrayList<>();

        try {
            // 个人的map
            Map<Integer, String> personMap = new HashMap<>();
            // 个人的Id随机数据
            List<Integer> personIds = new ArrayList<>();
            // 个人最终数据
            //List<List<Integer>> result = new ArrayList<List<Integer>>();
            // 随机抽取种子个数
            //int loop = 0;


            // 单位的map
            //Map<Integer, String> unitMap = new HashMap<>();
            // 单位的Id随机数据
            //List<Integer> unitIds = new ArrayList<>();
            // 单位的最终数据
            //List<Integer>  resultUnit = new ArrayList<>();

            // 获取个人数据集合
            List<Map<String, Object>> persons = (List<Map<String, Object>>) map.get("person");
            // 获取单位数据集合
            List<Map<String, Object>> units = (List<Map<String, Object>>) map.get("unit");


            List<List<Integer>> userParam = new ArrayList<>();
            Map<Integer,String> keymap = new HashMap<>();

            if (persons != null && persons.size() > 0) {
                for (Map<String, Object> person : persons) {
                    Integer id = (Integer) person.get("id");
                    personIds.add(id);
                    personMap.put(id, person.get("userName").toString());
                }
                for (int i = 0; i < units.size(); i++) {
                    List<Integer> integerList = new ArrayList<>();
                    int index1 = (int) (Math.random() * personIds.size());
                    int index2 = (int) (Math.random() * personIds.size());
                    while (index1 == index2) {
                        index2 = (int) (Math.random() * personIds.size());
                    }
                    Integer id1 = personIds.get(index1);
                    Integer id2 = personIds.get(index2);

                    integerList.add(id1);
                    integerList.add(id2);

                    keymap.put(id1,personMap.get(id1));
                    keymap.put(id2,personMap.get(id2));

                    userParam.add(integerList);
                }
                // TODO 需求变更，代码暂时先注释
                // 数据打乱生成随机数据
                //List<Integer> param = new ArrayList<Integer>();
                /*while (personIds.size() > 0) {
                    int index = (int) (Math.random() * personIds.size());
                    Integer name = personIds.get(index);
                    param.add(name);
                    personIds.remove(index);
                }
                // 进行分组 2人一组
                loop = param.size() / 2;
                for (int i = 0; i <= loop; i++) {
                    List<Integer> lists = new ArrayList<>();
                    if (i == loop) {
                        lists.addAll(param.subList(i * 2, param.size()));
                    } else {
                        lists.addAll(param.subList(i * 2, (i + 1) * 2));
                    }
                    // 不够两人的就剔除
                    if (lists.size() > 1) {
                        result.add(lists);
                    }
                }*/
            }

            for (int i = 0; i < units.size(); i++) {
                Map<String, Object> unitmap = new HashMap<>();
                // 用户Id
                List<Integer> listId = userParam.get(i);
                // 用户姓名集合
                List<String> listItem = new ArrayList<>();
                for (Integer id : listId) {
                    String username = keymap.get(id);
                    listItem.add(username);
                }
                unitmap.put("pname", StringUtil.join(listItem, ","));

                Map<String, Object> unitparam = units.get(i);
                unitmap.put("name", unitparam.get("usedPartyName").toString());

                Integer id = (Integer) unitparam.get("usedPartyId");
                unitmap.put("id", id);
                unitmap.put("userId", StringUtil.join(listId, ","));

                unitlist.add(unitmap);

            }
            // TODO 需求变更，代码暂时先注释
           /* if (units != null && units.size() > 0) {

                for (Map<String, Object> unit : units) {
                    Integer id = (Integer) unit.get("usedPartyId");
                    unitIds.add(id);
                    unitMap.put(id, unit.get("usedPartyName").toString());
                }

                while (unitIds.size() > 0) {
                    int index = (int) (Math.random() * unitIds.size());
                    Integer ger = unitIds.get(index);
                    if (resultUnit.size() != loop) {
                        resultUnit.add(ger);
                        unitIds.remove(index);
                    }else{
                        unitIds.remove(index);
                    }
                }


                for(int i=0;i<resultUnit.size();i++){
                    Map<String,Object> unitmap = new HashMap<>();
                    String unitname =unitMap.get(resultUnit.get(i));
                    unitmap.put("id",resultUnit.get(i));
                    unitmap.put("name",unitname);
                    *//*unitlist.add(unitmap);*//*

                    // 个人
                    List<Integer> integers = result.get(i);
                    List<String> userName = new ArrayList<>();
                    for(Integer in:integers){
                        String pname = personMap.get(in);
                        userName.add(pname);
                    }
                    unitmap.put("pname",StringUtil.join(userName,","));
                    unitlist.add(unitmap);
                }
            }*/
        } catch (Exception e) {
            logger.error("查询失败：" + e.getMessage(), e);
            return ResultUtil.returnError("查询失败", null);
        }
        return ResultUtil.returnSuccess(message, unitlist);
    }

    /**
     * 双随机分配完成后导出结果
     * @param map
     * @return
     */

    @Override
    public Map<String, Object> exportDistribution(Map map) {
        String message = "导出成功";
        Map<String, Object> result = new HashMap<>();
        try {
            List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("resuList");
            //如果查询结果不为空，则创建表格，否则不创建
            List<Map<String,Object>> paramList = new ArrayList<>();
            if (list != null && list.size() > 0) {
                // 模拟第一行数据
                Map<String, Object> pa = new HashMap<>();
                pa.put("name", "样板数据XX有限公司");
                pa.put("usrePartName", "使用单位");
                pa.put("partyName", map.get("partyName").toString());
                paramList.add(pa);


                for (Map<String, Object> objectMap : list) {
                    Map<String, Object> params = new HashMap<>();
                    params.put("name",objectMap.get("name").toString());
                    params.put("usrePartName","使用单位");
                    params.put("partyName",map.get("partyName").toString());

                    paramList.add(params);

                }

                // 1.获取保存路径，不存在则创建
                String tableName = "双随机一公开结果";//表名；
                // 创建 表头
                String[] tableN = {"单位名称", "属性","牵头检查单位"};

                String[] tableE = {"name", "usrePartName","partyName"};
                List<String> tablelist = Arrays.asList(tableN);
                List<String> tablelistEc = Arrays.asList(tableE);
                String path = environment.getProperty("upload", String.class);
                result = ExportExcelUtil.writeMapExcel(tableName, tablelist, tablelistEc, paramList, path);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            return ResultUtil.returnError(e.getMessage(), null);
        }
        return ResultUtil.returnSuccess(message, result);
    }

    /**
     * 获取是否是分局信息
     *
     * @param id
     * @return
     * @throws Exception
     */
    public String decideInfo(String id) {
        String limit = "0";
        // 判断市或者局  通过传入Id判断  0是市级 1是局级 2 是分局
        List<Party> partys = partyMapp.decideBranchInfo(id);
        if (partys != null && partys.size() > 0) {
            List<Party> partyList = partyMapp.decideForEach(id);
            if (partyList != null && partyList.size() > 0) {
                limit = "0";
            } else {
                // 此时为局
                limit = "1";
            }
        } else {
            limit = "2";
        }
        return limit;
    }
}
